home *** CD-ROM | disk | FTP | other *** search
- /*
- Change - text file line changer
-
- last modified : 23 October 1983
-
- usage: Change <from_string> <to_string> <filename> [<file2> <filen> -d -n -q -r]
-
- Warning: generic filenames (* and ?) not implemented with CI-C86.
-
- Change is a text search and replace program for multiple files. It
- is useful for replacing text strings common to a batch of files,
- for instance all the source files for a long program.
-
- The command line file specifer(s) may be one or more ambiguous or
- non-ambiguous file names.
-
- For example:
-
- Change from to foo <- chg operates on the file foo only
- Change from to foo bar.* <- operates on the files foo, and any
- expansions of bar.*
- Change from to *.c?? <- chg operates on all files of type c
- Change from to *.c* <- same as above
-
- The command line dash options are:
- -d(isplay) <- display all changes on the console
- as they occur
- -n(o line numbers) <- turns line numbering off (only
- valid with -d option
- -q(uery) <- prompt and ask before each change
- -r(etain original) <- output (for each input file) goes to
- the (created) file <infile.$$> (the
- '$$' extention is added)
- in default operation, the original
- file is rename to type 'BAK' and
- output goes to a newly created file
- with the same name as the original
- input file.
-
- Copyright (c) 1983 by
- Tony Rowe
- 3260 So. Penn
- Englewood, Co. 80110
-
- (303) 761-0755
- */
-
- #include <stdio.h>
- #define TRUE 1
- #define FALSE 0
- #define ERROR (-1)
-
- #define MAXLEN 300
- #define bool char
- #define INPUT "r"
- #define OUTPUT "w"
- #define DEFTYP ".$$"
- #define BAKTYP ".BAK"
- #define YES TRUE
- #define NO FALSE
-
- /* externals used mainly for the sake of speed */
- FILE *InFile; /* disk file pointers */
- FILE *OutFile;
- char LineBuffer[2*MAXLEN]; /* line buffer */
- char SearchPattern[MAXLEN]; /* search pattern buffer */
- char ReplacementPattern[MAXLEN]; /* replace pattern string buffer */
- char *Cp; /* general purpose character pointer */
- int Line; /* line number */
- bool ShowLineNumbers, ShowChanges, /* option flags */
- AskBeforeChanging, RetainOriginalFile;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char OutFName[MAXLEN]; /* output file name buffer */
- char BackupFName[MAXLEN]; /* backup file name buffer */
- char RestOfString[2*MAXLEN]; /* rest of string buffer */
- short arg; /* argv index */
- int ChangeFile(); /* routine to change strings */
-
- "Copyright (c) 1983 by Tony Rowe";
-
- ShowChanges = AskBeforeChanging = RetainOriginalFile = FALSE;
- ShowLineNumbers = TRUE;
-
- if (argc < 4) {
- printf("%s\n%s\n",
- "Usage: Change from_string to_string filename [filename...]",
- "\t[-d(isplay) -n(o numbers) -q(uery) -r(etain original)]");
- exit();
- }
-
- #ifdef CONSOLE
- printf("\nSearch pattern: ");
- fgets(SearchPattern, MAXLEN, stdin);
- if (SearchPattern[0] == '\0')
- exit();
- printf("Replacement pattern: ");
- fgets(ReplacementPattern, MAXLEN, stdin);
- #else /* not CONSOLE */
- strcpy(SearchPattern, argv[1]);
- strcpy(ReplacementPattern, argv[2]);
- if (! strcmp(ReplacementPattern, "\"\""))
- strcpy(ReplacementPattern, "");
- #endif /* def CONSOLE */
-
- /* check args for options */
- for (arg = 1; arg < argc; ++arg) {
- if (argv[arg][0] == '-') {
- switch (toupper(argv[arg][1])) {
- case 'N':
- ShowLineNumbers = FALSE;
- continue;
- case 'Q':
- AskBeforeChanging = TRUE;
- case 'D':
- ShowChanges = TRUE;
- continue;
- case 'R':
- RetainOriginalFile = TRUE;
- continue;
- default:
- printf("\nBad option: %s\n", argv[arg]);
- }
- }
- }
-
- /* process filenames from command line, skipping '-' options */
- for (arg = 3; arg < argc; ++arg) {
- if (argv[arg][0] == '-') {
- switch (toupper(argv[arg][1])) {
- case 'D':
- case 'N':
- case 'Q':
- case 'R':
- continue;
- } /* switch */
- } /* if */
- ProcessFiles(argv[arg], ChangeFile);
- } /* for */
- } /* main () */
-
-
- ChangeFile (FileName)
- char *FileName;
- {
- char OutFName[MAXLEN]; /* output file name buffer */
- char BackupFName[MAXLEN]; /* backup file name buffer */
- char RestOfString[2*MAXLEN]; /* rest of string buffer */
- int PatternLength; /* length of replacement pattern */
- bool FoundSearchPattern; /* save output file flag */
-
- "Copyright (c) 1983 by Tony Rowe";
-
- /* don't process any .COM files */
- for (Cp = FileName; *Cp != '\0' && *Cp != '.'; ++Cp)
- ;
- if (! strcmp(Cp, ".COM"))
- return;
-
- if ((InFile = fopen(FileName, INPUT)) == NULL) {
- printf("\nNo file: %s\n", FileName);
- return;
- }
- /* make output filenames */
- strcpy(OutFName, FileName);
- for (Cp = OutFName; *Cp != '\0' && *Cp != '.'; ++Cp)
- ;
- *Cp = '\0';
- strcpy(BackupFName, OutFName);
- strcat(OutFName, DEFTYP);
- strcat(BackupFName, BAKTYP);
-
- if ((OutFile = fopen(OutFName, OUTPUT)) == NULL)
- exit(printf("Can't create: %s\n", OutFName));
-
- PatternLength = strlen(SearchPattern);
- FoundSearchPattern = NO;
-
- for (Line = 0; fgets(LineBuffer, MAXLEN, InFile); ++Line) {
- for (Cp = LineBuffer; *Cp; ++Cp) {
- if (strmatch(Cp, SearchPattern)) {
- if ( (! FoundSearchPattern) && ShowChanges)
- printf("\n%s\n", FileName);
- FoundSearchPattern = YES;
- if (ShowChanges) {
- ShowLineNumbers?
- printf("\n%05d: %s", Line, LineBuffer):
- printf(LineBuffer);
- if (AskBeforeChanging) {
- putpointer(LineBuffer, Cp - LineBuffer,
- ShowLineNumbers? 8: 0);
- if (! askyn(" Change"))
- continue;
- }
- }
- strcpy(RestOfString, Cp + PatternLength);
- strcpy(Cp, ReplacementPattern);
- Cp += PatternLength + 1;
- strcat(LineBuffer, RestOfString);
- if (ShowChanges) {
- ShowLineNumbers?
- printf("%05d: %s", Line, LineBuffer):
- printf(LineBuffer);
- }
- }
- }
- if (fputs(LineBuffer, OutFile) == ERROR) {
- printf("Error writing a line to: %s\n", OutFName);
- exit();
- }
- }
-
- fclose(InFile);
-
- if (FoundSearchPattern) {
- if (fclose(OutFile) == ERROR) {
- printf("Can't close: %s\n", OutFName);
- exit();
- }
- if (RetainOriginalFile) {
- unlink(BackupFName);
- rename(FileName, BackupFName);
- rename(OutFName, FileName);
- }
- else {
- unlink(FileName);
- rename(OutFName, FileName);
- }
- }
- else {
- fclose(OutFile);
- unlink(OutFName);
- }
- } /* ChangeFile () */
-
-
- strmatch(str, pat)
- char *str, *pat;
- {
- while (*pat)
- if (*str++ != *pat++)
- return NO;
- return YES;
- }
-
- askyn(prompt)
- char *prompt;
- {
- while (TRUE) { /* forever */
- printf(prompt);
- printf(" ? ");
- switch (GetInKey()) {
- case 'y':
- case 'Y':
- printf("yes\t\t\n");
- return YES;
- case 'n':
- case 'N':
- printf("no\t\t\n");
- return NO;
- case '\3': /* control-C */
- printf("^C");
- exit();
- default:
- printf("\n(Y or N) \n");
- }
- }
- }
-
- /* put a string like " ^\n" on the console, left padded with spaces
- * so that the '^' character is below string[index] on the screen.
- * allow for tabs in the source string
- */
- putpointer(string, index, offset)
- char *string;
- short index, offset;
- {
- short i;
-
- while (offset--)
- printf(" ");
- for (i = 0; i < index; ++i)
- printf(string[i] == '\t'? "\t": " ");
- printf("^\n");
- }
- while (offset--)
- printf(" ");
- for (i =